package org.icnmasjid.member.webapp.action;

import java.beans.PropertyEditorSupport;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.icnmasjid.member.webapp.action.BaseFormController;
import org.icnmasjid.member.model.Registration;
import org.icnmasjid.member.service.Manager;
import org.icnmasjid.member.service.RegistrationManager;
import org.springframework.validation.BindException;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.servlet.ModelAndView;

public class RegistrationFormController extends BaseFormController {
    private RegistrationManager registrationManager = null;

    public RegistrationFormController() {
        setCommandName("registration");
        setCommandClass(Registration.class);
    }

    protected boolean isFormSubmission(HttpServletRequest request) {
    	return true;
    }

    protected Object formBackingObject(HttpServletRequest request)
    throws Exception {
    	Registration registration = null;
        String id = request.getParameter("id");
        if (StringUtils.isNotBlank(id)) {
            registration = registrationManager.getRegistration(id);
        } else {
        	registration = new Registration();
        }
        return registration;
    }

    protected void onBindAndValidate(HttpServletRequest request, Object command, BindException errors) throws Exception {
    	super.onBindAndValidate(request, command, errors);
    	Registration registration = (Registration)command;
    	if ( request.getParameter("modify") != null ) {
    		if ( StringUtils.isNotBlank(registration.getPhone()) && registration.getPhone().length() != 10 ) {
    			errors.rejectValue("phone", "errors.phone", new Object[] {registration.getPhone()}, "invalid phone number");
    		}
			if ( StringUtils.isNotBlank(registration.getTicketNumbers()) ) {
				String errorCode = validTicketsNumbers(registration);
				if ( errorCode != null ) {
					errors.rejectValue(
						"ticketNumbers",
						errorCode,
						new Object[] {registration.getTicketNumbers()},
						"invalid ticket numbers"
					);
				}
				if ( registration.getTicketNumbers().split("\n").length != registration.getNumberTickets() ) {
	    			errors.rejectValue(
	    				"numberTickets",
	    				"errors.numberOfTickets",
	    				new Object[]{registration.getNumberTickets()},
	    				"ticket numbers and number of tickets dont match"
	    			);
				}
			}
    		if ( StringUtils.isBlank(registration.getFirstName()) ) {
    			errors.rejectValue("firstName", "errors.required", new Object[]{"First Name"},"First Name must be specified");
    		}
    	}

    }


	private String validTicketsNumbers(Registration registration) {
		String ticketNumbers = registration.getTicketNumbers();
		// parse the tickets numbers
		// make sure the numbers are four digits
		// make sure the numbers are not used by another record
		String[] numbers = ticketNumbers.split("\n");
		// check the numbers are four chars
		List<String> list = Arrays.asList(numbers);
		for ( String number: list) {
			String n = StringUtils.deleteWhitespace(number);
			if ( n.length() != 4  ) {
				return "errors.ticketNumbers.4digits";
			}
			if ( !StringUtils.isNumeric(n) ) {
				return "errors.ticketNumbers.allNumbers";
			}
			if ( registration.getId() == null ) {
				Registration reg = new Registration();
				reg.setTicketNumbers(n);
				if ( registrationManager.getRegistrations(reg).size() > 0 ) {
					return "errors.ticketNumbers.alreadyExist";
				}
			}
		}
		return null;
	}

	protected ModelAndView showForm(HttpServletRequest request, HttpServletResponse response, BindException errors, Map controlModel) throws Exception {
		ModelAndView mav = super.showForm(request, response, errors, controlModel);
		if ( errors.getErrorCount() > 0) {
			if ( request.getParameter("search") != null ) {
				mav.setViewName("ajax_registrationList");
			} else {
	            mav.addObject("registration", errors.getTarget());
				mav.setViewName("ajax_editRegistration");
			}
		}
		return mav;
	}

    public ModelAndView onSubmit(HttpServletRequest request,
                                 HttpServletResponse response, Object command,
                                 BindException errors)
    throws Exception {
        if (log.isDebugEnabled()) {
            log.debug("entering 'onSubmit' method...");
        }
        Registration registration = (Registration) command;
        ModelAndView mav = new ModelAndView("registrationList", "registration", registration);
        if ( request.getParameter("search") != null ) {
        	mav.addObject("registrations", registrationManager.getRegistrations(registration));
        	mav.setViewName("ajax_registrationList");
        }
        if (request.getParameter("modify") != null) {
            boolean isNew = (registration.getId() == null);
            Locale locale = request.getLocale();
            registrationManager.saveRegistration(registration);
            String key = (isNew) ? "registration.added" : "registration.updated";
            saveMessage(request, getText(key, locale));
            mav.addObject("registration", registration);
            mav.setViewName("ajax_editRegistration");
        }
        if (request.getParameter("get") != null) {
            mav.addObject("registration", registration);
            mav.setViewName("ajax_editRegistration");
        }
        return mav;
    }

	public void setRegistrationManager(RegistrationManager registrationManager) {
		this.registrationManager = registrationManager;
	}
}